﻿#include <string>
#include <thread>
#include <cstdio>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include "public_define.h"

#include "sys/stat.h"
#include "eventloop.h"
#include "filemanager.h"
#include "filemanagercommand.h"

#include <stdio.h>
#include <sys/statvfs.h>

#include "data_record.h"
#include "adr_trigger.h"

#define FLUSH_NUM 8

using namespace fileRegion;
using namespace DcAdr;

const string saveFileInfoName = "./adrSystem/fileInfo.txt";
const string FileManagerRule = "FileManagerRule";
const string Folder = "Folder";

DataStore::DataStore()
{
}

DataStore::~DataStore()
{
}

void DataStore::writeInfoMapToLocal(string fileInfoData)
{
    fileInfoData += "\r\n";
    fstream f(saveFileInfoName.c_str(), ios::app);
    f.write(fileInfoData.c_str(), fileInfoData.length());
    f.close();
}

FileManager::FileManager()
{
}
FileManager::~FileManager()
{
}

string FileManager::saveFileToPath(string fileName, string folderPath)
{
    string tmpFileName = fileName.substr(fileName.find_last_of("/") + 1);
    string newFileName = folderPath + "/" + tmpFileName;

    int ret = rename(fileName.c_str(), newFileName.c_str());
    Log_Info("rename:{} to :{} ret:{}", fileName, newFileName, ret);

    if (0 != ret)
    {
        Log_Info("rename failed");
        return "";
    }
    return newFileName;
}

string FileManager::cpFileToPath(string fileName, string folderPath)
{
    // cout<<__func__<<":"<<__LINE__<<endl;
    string tmpFileName = fileName.substr(fileName.find_last_of("/") + 1);
    string newFileName = folderPath + "/" + tmpFileName;

    // cout<<"tmpFileName:"<<tmpFileName<<" newFileName:"<<newFileName<<endl;
    // cout<<__func__<<":"<<__LINE__<<endl;
    ifstream in(fileName, ios::binary);
    ofstream out(newFileName, ios::binary);
    // cout<<__func__<<":"<<__LINE__<<endl;
    if (!in)
    {
        // cout<<__func__<<":"<<__LINE__<<endl;
        return "";
    }

    if (!out)
    {
        // cout<<__func__<<":"<<__LINE__<<endl;
        return "";
    }

    char flush[FLUSH_NUM];
    while (!in.eof())
    {
        in.read(flush, FLUSH_NUM);
        out.write(flush, in.gcount());
    }
    // cout<<__func__<<":"<<__LINE__<<endl;
    in.close();
    out.close();
    // cout<<__func__<<":"<<__LINE__<<endl;

    return newFileName;
}

double FileManager::judgeFileToFolder(double fileSize,
                                      double folderSize,
                                      double folderUseSize,
                                      double alarmThreshold,
                                      double safetyThreshold)
{
    if (alarmThreshold < safetyThreshold)
    {
        return -1.0;
    }
    if ((fileSize + folderUseSize) >= (folderSize * alarmThreshold))
    {
        return ((fileSize + folderUseSize) - (folderSize * safetyThreshold));
    }
    else
    {
        return 0.0;
    }
}

void L3FileManager::setFileManagerCfgPath(const string &fileManagerCfgPath)
{
    m_fileManagerCfgPath = fileManagerCfgPath; 

    creatPathAndMove();
    readFileManagerCfg();
    return;
}

//计算分配给adr存储dat目录的大小：
void L3FileManager::calculateMaxSize(string folder)
{
    // /ds/datacollect 
    struct statvfs stat;
    unsigned long freeSpace = 0;
    if (statvfs(global_data::g_file_path.c_str(), &stat) == 0)
    {
        // 计算可用空间（以 MB 为单位）
        freeSpace = (unsigned long)stat.f_bavail * stat.f_frsize;        
        Log_Info("/ds/ free_size:{} MB!!!", freeSpace/(1024 * 1024));// /ds /ds free空间大小
    }
    else 
    {
        Log_ERROR("read /ds/ avalid size faild !!!");
    }

    double useSize = stod(m_folderInfoData[folder]["folderUsingSize"]);// /ds/datacollect/gerneral/level2 具体某个目录已用大小
    Log_Info("{} used_size:{} MB!!!", folder, useSize/(1024 * 1024));

    double configSize = stod(m_folderInfoData[folder]["configSize"]);// /ds/datacollect/gerneral/level2 配置大小
    Log_Info("{} config_Size:{} MB!!!", folder, configSize/(1024 * 1024));


    //每次写dat时，计算folderMaxSize ；如果 free空间 > 配置,用配置大小。  否则表示内存不充足，考虑剩余大小+adr已用大小；
    if (freeSpace > configSize)//configSize :5120
    {
        m_folderInfoData[folder]["folderMaxSize"] = to_string(configSize);//分配给这个文件夹的大小
        Log_Info("[use_config] is enough; folder:{} maxsieze:{} MB!!!", folder, configSize/(1024 * 1024));
    }
    else if ((useSize + freeSpace) > configSize)//剩余大小+adr已用大小 比配置大，用配置
    {
        m_folderInfoData[folder]["folderMaxSize"] = to_string(configSize);
        Log_Info("[use_config] folder:{} maxsieze:{} MB!!!", folder, configSize / (1024 * 1024));
    }
    else
    {
        m_folderInfoData[folder]["folderMaxSize"] = to_string(useSize + freeSpace);
        Log_Info("[use_left&use] folder:{} maxsieze:{} MB!!!", folder, (useSize + freeSpace) / (1024 * 1024));
    }
    return;
}

void L3FileManager::MoveTmpFile()
{
    Log_Info("move dat start");

    ///ds/datacollect 会有之前的文件，导致savefile/total/目录文件管理做失败，移到里面。后续文件分级这也要改 zjs_todo;
    
    string folderPath = "/ds/datacollect";
    DIR *dir = opendir(folderPath.c_str());
    if (NULL == dir)
    {
        Log_Info("目录文件:{}  打开失败!!!", folderPath);
        return;
    }

    struct dirent *dir_info;
    struct stat s_buf;

    std::string absPath = "";
    std::string fileName = "";

    while ((dir_info = readdir(dir))!=nullptr)
    {
        fileName = dir_info->d_name;
        std::string eventName;

        if (fileName.find(".dat") != std::string::npos)
        {
            eventName = DataRecord::getEvtFromDat(fileName);
        }

        absPath = folderPath + "/" + dir_info->d_name;

        int retCI = stat(absPath.c_str(), &s_buf);
        (void)retCI;
        if (!S_ISDIR(s_buf.st_mode))//非目录dat文件提取出 eventName，move到相应文件夹
        {
            auto tmplev = AdrTrigger::getInstance().getEventLevl(eventName);
            auto tmpFolderIdIter = m_folderIdInfo.find(tmplev);
            if (tmpFolderIdIter != m_folderIdInfo.end())
            {
                string folderName = tmpFolderIdIter->second;
                std::string rmCmd = "mv " + absPath + " " + folderName;
                auto resSys = system(rmCmd.c_str());
                Log_Info("move dat:{} ret:{}", rmCmd, resSys);
            }
        }
    }
    closedir(dir);


#if 0
    //aeb目录
    {
        std::string rmCmd = "mv /ds/datacollect/*BA067.dat /ds/datacollect/savefile/aeb/";
        auto resSys = system(rmCmd.c_str());
        Log_Info("move dat:{} ret:{}", rmCmd, resSys);
    }
    {
        std::string rmCmd = "mv /ds/datacollect/*BA067.dat.gz /ds/datacollect/savefile/aeb/";
        auto resSys = system(rmCmd.c_str());
        Log_Info("move dat:{} ret:{}", rmCmd, resSys);
    }

    {
        std::string rmCmd = "mv /ds/datacollect/*.dat /ds/datacollect/savefile/total/";
        auto resSys = system(rmCmd.c_str());
        Log_Info("move dat:{} ret:{}", rmCmd, resSys);
    }
    {
        std::string rmCmd = "mv /ds/datacollect/*.dat.gz /ds/datacollect/savefile/total/";
        auto resSys = system(rmCmd.c_str());
        Log_Info("move dat:{} ret:{}", rmCmd, resSys);
    }
#endif
}

void L3FileManager::creatPathAndMove()
{
    ///ds/datacollect/savefile
    std::string command = "rm -rf /ds/datacollect/savefile";
    int retCI = system(command.c_str());
    Log_Info("system_command :{}  retCI:{}", command, retCI);

    string fileInfoCfgName = m_fileManagerCfgPath;

    ifstream infile(fileInfoCfgName);
    if (infile)
    {
        string strline = "";
        while (getline(infile, strline))
        {
            if (!strline.empty())
            {
                vector<string> vfolder = Util::split_vec(strline, ",");
                if (vfolder.size() == 5)
                {
                    m_folderIdInfo[stoi(vfolder.at(0).c_str())] = m_absolutePath + vfolder[1];

                    createPath(m_absolutePath + vfolder[1]);

                }
            }

            strline.clear();
        }

        infile.close();
    }
    else
    {
        Log_Info("***Not find:{} !!!", fileInfoCfgName);
    }

    MoveTmpFile();
}

int L3FileManager::readFileManagerCfg()
{
    string fileInfoCfgName = m_fileManagerCfgPath;

    ifstream infile(fileInfoCfgName);
    if (infile)
    {
        string strline = "";
        while (getline(infile, strline))
        {
            if (!strline.empty())
            {
                vector<string> vfolder = Util::split_vec(strline, ",");
                if (vfolder.size() == 5)
                {
                    m_folderInfoData[m_absolutePath + vfolder[1]]["configSize"] = to_string(stod(vfolder[2].c_str()) * 1024 * 1024);

                    dealFolder(m_absolutePath + vfolder[1]);

                    calculateMaxSize(m_absolutePath + vfolder.at(1));

                    m_folderInfoData[m_absolutePath + vfolder[1]]["alarmThreshold"] = vfolder[3];
                    m_folderInfoData[m_absolutePath + vfolder[1]]["safetyThreshold"] = vfolder[4];

                }
            }

            strline = "";
        }

        infile.close();
    }
    else
    {
        Log_Info("***Not find:{} !!!", fileInfoCfgName);
    }
    return 0;
}

L3FileManager::L3FileManager() : m_absolutePath("")
{
    m_delTimeRuleFlag = 0;
    m_delApathyFactorFlag = 0;

    m_absolutePath = global_data::g_file_path + m_absolutePath;

    int ret = access(m_absolutePath.c_str(), F_OK);
    if (0 != ret)
    {
        int retCI = mkdir(m_absolutePath.c_str(), S_IRWXU);
        (void)retCI;
    }
    //Log_Info("m_absolutePath :{} ", m_absolutePath);
}

void L3FileManager::dealFolder(string folderName)
{
    int ret = access(folderName.c_str(), F_OK);
    if (0 == ret)
    {
        getFolderAllFileInfo(folderName);
    }
    else
    {
        std::string command = "mkdir -p " + folderName;
        int retCI = system(command.c_str());
        Log_Info("zjs_tmp_0415; command :{}  retCI:{}", command, retCI);

        m_folderInfoData[folderName]["folderUsingSize"] = to_string(0.0);
    }

    return;
}

void L3FileManager::createPath(string folderName)
{
    int ret = access(folderName.c_str(), F_OK);
    if (0 != ret)
    {
        std::string command = "mkdir -p " + folderName;
        int retCI = system(command.c_str());
        Log_Info("zjs_tmp_0415; command :{}  retCI:{}", command, retCI);

        m_folderInfoData[folderName]["folderUsingSize"] = to_string(0.0);
    }

    return;
}

void L3FileManager::getFolderAllFileInfo(string folderPath)
{
    // // cout<<__func__<<__LINE__<<"  folderPath:"<<folderPath<<endl;
    DIR *dir = opendir(folderPath.c_str());
    if (NULL == dir)
    {
        Log_Info("目录文件:{}  打开失败!!!", folderPath);
        return;
    }

    struct dirent *dir_info;
    struct stat s_buf;
    std::map<std::string, std::string> tmpFileInfoMap;
    double tmpTotalSize = 0.0;

    std::string absPath = "";
    while ((dir_info = readdir(dir))!=nullptr)
    {
        absPath = folderPath + "/" + dir_info->d_name;

        int retCI = stat(absPath.c_str(), &s_buf);
        (void)retCI;

        if (!S_ISDIR(s_buf.st_mode))
        {
            // // cout<<"dir_info->d_name:"<<dir_info->d_name<<" s_buf.st_mtime:"<<s_buf.st_mtime<<" s_buf.st_size"<<s_buf.st_size<<endl;
            // // cout<<"dir_info->d_name:"<<dir_info->d_name<<" s_buf.st_ctime:"<<s_buf.st_ctime<<" s_buf.st_size"<<s_buf.st_size<<endl;
            // // cout<<"dir_info->d_name:"<<dir_info->d_name<<" s_buf.st_atime:"<<s_buf.st_atime<<" s_buf.st_size"<<s_buf.st_size<<endl;

            tmpTotalSize += s_buf.st_size;
            tmpFileInfoMap[to_string(s_buf.st_mtime) + string(dir_info->d_name)] = string(dir_info->d_name) + "&" + to_string(s_buf.st_size);
            Log_Info("folderPath:{},timeAndName:{},nameAndSize:{}",folderPath,to_string(s_buf.st_mtime) + string(dir_info->d_name),string(dir_info->d_name) + "&" + to_string(s_buf.st_size));
            // // cout<<"filename: "<<string(dir_info->d_name)<<" size:"<<to_string(s_buf.st_size)<<endl;
        }
    }

    m_folderAllFileInfo[folderPath] = tmpFileInfoMap;
    m_folderInfoData[folderPath]["folderUsingSize"] = to_string(tmpTotalSize);
    
    // // cout<<"folderPath:"<<folderPath<<" tmpTotalSize:"<<m_folderInfoData[folderPath]["folderUsingSize"]<<endl;

    closedir(dir);

    return;
}
void L3FileManager::delFileUploadSuccess(string filePathAndName)
{
    //Log_Info("[delFileUploadSuccess] fileName:{}", filePathAndName);
    std::map<string, string> tmpFileInfoMap;
    std::map<string, string> tmpFolderInfoMap;
    string folderPath = Util::getFilePath(filePathAndName);
    if (!folderPath.empty())
    {
        folderPath.pop_back();
    }
    Log_Info("delFileUploadSuccess folderPath:{},fileName:{}", folderPath,filePathAndName);
    auto tmpFileInfoIter = m_folderAllFileInfo.find(folderPath);// levle2  map<0705-14:20-1.txt, 1.txt&1.1M> 
    if (tmpFileInfoIter != m_folderAllFileInfo.end())
    {
        tmpFileInfoMap = tmpFileInfoIter->second;

        for (auto beg = tmpFileInfoMap.begin(); beg != tmpFileInfoMap.end();)
        {
            string fileInfo = beg->second;
            string fileCreateTime=beg->first;
            string fileName = fileInfo.substr(0, fileInfo.find_last_of("&"));
            string tmpfilePathAndName = folderPath + "/" + fileName;
            //Log_Info("tmpfilePathAndName:{},fileInfo:{},fileCreateTime:{},filePathAndName:{}",tmpfilePathAndName,fileInfo,fileCreateTime,filePathAndName);
            if (tmpfilePathAndName == filePathAndName)
            {
                double tmpfileSize = stod((fileInfo.substr(fileInfo.find_last_of("&") + 1)).c_str());

                int retCI = remove(filePathAndName.c_str());
                (void)retCI;
                // 增加文件上传成功删除文件日志打印
                Log_Info("uplaod success remove file:{},file size:{}", filePathAndName,tmpfileSize);
                tmpFileInfoMap.erase(beg);
                auto tmpFolderInfoIter = m_folderInfoData.find(folderPath);
                if (tmpFolderInfoIter != m_folderInfoData.end())
                {
                    tmpFolderInfoMap = tmpFolderInfoIter->second;
                    auto tmpFolderValueIter = tmpFolderInfoMap.find("folderUsingSize");

                    if (tmpFolderValueIter != tmpFolderInfoMap.end())
                    {
                        double useFolderSize = stod((tmpFolderValueIter->second).c_str());
                        useFolderSize -= tmpfileSize;
                        tmpFolderValueIter->second = to_string(useFolderSize);
                    }

                    m_folderInfoData[folderPath] = tmpFolderInfoMap;
                    Log_Info("after upload success file remove folderPath:{},use size:{}",folderPath,stod(m_folderInfoData[folderPath]["folderUsingSize"]));
                }

                m_folderAllFileInfo[folderPath] = tmpFileInfoMap;

                break;
            }
            beg++;
        }
    }
    return;
}
void L3FileManager::delFileFromPath(string folderPath, double fileSize)
{
    // // cout<<__func__<<":"<<__LINE__<<":"<<" folderPath:"<<folderPath<<" fileSize:"<<to_string(fileSize)<<endl;

    std::map<string, string> tmpFileInfoMap;
    std::map<string, string> tmpFolderInfoMap;
    double delTotalFileSize = 0.0;

    if (folderPath.empty())
    {
        Log_Info("folderPath:{} is empty!!!", folderPath);
        return;
    }

    if (fileSize <= 1.0)
    {
        Log_Info("fileSize:{} is less than 1.0!!!", fileSize);
        return;
    }
    auto tmpFileInfoIter = m_folderAllFileInfo.find(folderPath);
    if (tmpFileInfoIter != m_folderAllFileInfo.end())
    {
        tmpFileInfoMap = tmpFileInfoIter->second;

        for (auto beg = tmpFileInfoMap.begin(); beg != tmpFileInfoMap.end();)
        {
            string fileInfo = beg->second;
            string fileName = fileInfo.substr(0, fileInfo.find_last_of("&"));
            double tmpfileSize = stod((fileInfo.substr(fileInfo.find_last_of("&") + 1)).c_str());


            int retCI = remove((folderPath + "/" + fileName).c_str());
            (void)retCI;
            // 增加文件老化日志打印
            Log_Info("[L3FileManager][delFileFromPath] remove old file:{},filesize:{}", folderPath + "/" + fileName,tmpfileSize);
            tmpFileInfoMap.erase(beg++);

            delTotalFileSize += tmpfileSize;

            if (delTotalFileSize >= fileSize)
            {
                auto tmpFolderInfoIter = m_folderInfoData.find(folderPath);
                if (tmpFolderInfoIter != m_folderInfoData.end())
                {
                    tmpFolderInfoMap = tmpFolderInfoIter->second;
                    auto tmpFolderValueIter = tmpFolderInfoMap.find("folderUsingSize");

                    if (tmpFolderValueIter != tmpFolderInfoMap.end())
                    {
                        double useFolderSize = stod((tmpFolderValueIter->second).c_str());
                        useFolderSize -= delTotalFileSize;
                        tmpFolderValueIter->second = to_string(useFolderSize);
                    }

                    m_folderInfoData[folderPath] = tmpFolderInfoMap;
                    Log_Info("after old file remove folderPath:{},use size:{}",folderPath,stod(m_folderInfoData[folderPath]["folderUsingSize"]));
                }

                m_folderAllFileInfo[folderPath] = tmpFileInfoMap;

                break;
            }
        }
    }

    return;
}

uint8_t L3FileManager::getFileLevel(std::vector<int> vecEventid, int *regulAreaFlag)
{
    *regulAreaFlag = 0;
    uint8_t fileLevel = E_EventLevel_err;
    uint8_t retLevel = E_EventLevel_err;

    for (auto vecEventIdIter : vecEventid)
    {
        switch (vecEventIdIter)
        {
        case E_EVENT_BA067_ID:
        case E_EVENT_BA515_ID:
        case E_EVENT_BA516_ID:        
        {
            *regulAreaFlag = 1;
            fileLevel = E_EventLevel_1;
            break;
        }
        // case E_EVENT_POTENTIAL_ID:
        // case E_EVENT_TAKENOW_ID:
        // case E_EVENT_MANUALRECORD_ID:
        // {
        //     fileLevel = E_EventLevel_2;
        //     break;
        // }
        default:
        {
            fileLevel = E_EventLevel_err;
            break;
        }
        }

        if (retLevel > fileLevel)
        {
            retLevel = fileLevel;
        }
    }

    return retLevel;
}

uint8_t L3FileManager::getFolderId(uint8_t fileLevel, uint8_t fileType)
{
    uint8_t retFolderId = E_FileTypeErr_ID;
    switch (fileLevel)
    {
    case E_EventLevel_0:
    {
        retFolderId = E_AccidentAndCollision_ID;
        break;
    }
    case E_EventLevel_1:
    {
        if (FT_CanMiddata == fileType)
        {
            retFolderId = E_CanMidData_1_ID;
        }
        else if (FT_VEDIO == fileType)
        {
            retFolderId = E_VEDIO_1_ID;
        }
        else
        {
            retFolderId = E_PICTURE_1_ID;
        }        
        break;
    }
    case E_EventLevel_2:
    {
        if (FT_CanMiddata == fileType)
        {
            retFolderId = E_CanMidData_2_ID;
        }
        else if (FT_VEDIO == fileType)
        {
            retFolderId = E_VEDIO_2_ID;
        }
        else
        {
            retFolderId = E_PICTURE_2_ID;
        }        
        break;
    }
    case E_EventLevel_3:
    {
        if (FT_CanMiddata == fileType)
        {
            retFolderId = E_CanMidData_3_ID;
        }
        else if (FT_VEDIO == fileType)
        {
            retFolderId = E_VEDIO_3_ID;
        }
        else
        {
            retFolderId = E_PICTURE_3_ID;
        }        
        break;
    }
    default:
    {
        break;
    }
    }

    return retFolderId;
}

uint8_t L3FileManager::getFolderId(uint8_t fileLevel)
{
    uint8_t retFolderId = 6;
    switch (fileLevel)
    {
    case 1:
    {
        retFolderId = 1;
        break;
    }
    case 2:
    {
        retFolderId = 2;
        break;
    }
    case 3:
    {
        retFolderId = 3;
        break;
    }
    case 4:
    {
        retFolderId = 4;
        break;
    }
	case 5:
	{
		retFolderId = 5;
		break;
	}
	case 6:
	{
		retFolderId = 6;
		break;
	}
    default:
    {
        break;
    }
    }

    return retFolderId;
}

string L3FileManager::saveFile(int level, const string &fileName)
{
    std::map<string, string> tmpFolderInfoMap;
    double folderMaxSize = 0.0;
    double alarmThreshold = 0.0;
    double safetyThreshold = 0.0;
    double folderUsingSize = 0.0;
    string newFilePath = "";
    int regulAreaFlag = 0;
    (void)regulAreaFlag;

#if 0
    //根据事件和文件类型决定放到哪个位置
    uint8_t tmpFileLevel = getFileLevel(vecEventid, &regulAreaFlag);
    if (E_EventLevel_err == tmpFileLevel)
    {
        // cout<<"eventID is error, tmpFileLevel is "<<(int)tmpFileLevel<<endl;
        return newFilePath;
    }
    uint8_t tmpFolderId = getFolderId(tmpFileLevel, fileType);
#endif

    uint8_t tmpFolderId = getFolderId(level);

    auto tmpFolderIdIter = m_folderIdInfo.find(tmpFolderId);

    if (tmpFolderIdIter != m_folderIdInfo.end())
    {
        string folderName = tmpFolderIdIter->second;

        int ret = access(fileName.c_str(), F_OK);
        if (0 != ret)
        {
            // cout<<"saveFile fileName:"<<fileName<<" not exist!!!"<<endl;
            return newFilePath;
        }

        struct stat s_buf;
        ret = stat(fileName.c_str(), &s_buf);

        // if(!S_ISDIR(s_buf.st_mode))
        // {
        // 	// cout<<"dir_info->d_name:"<<fileName<<"s_buf.st_mtime1:"<<s_buf.st_mtime<<" s_buf.st_size"<<s_buf.st_size<<endl;
        //     // cout<<"dir_info->d_name:"<<fileName<<"s_buf.st_ctime1:"<<s_buf.st_ctime<<" s_buf.st_size"<<s_buf.st_size<<endl;
        //     // cout<<"dir_info->d_name:"<<fileName<<"s_buf.st_atime1:"<<s_buf.st_atime<<" s_buf.st_size"<<s_buf.st_size<<endl;

        // }

        double tmpFileSize = s_buf.st_size;

        auto tmpFolderInfoIter = m_folderInfoData.find(folderName);
        if (tmpFolderInfoIter != m_folderInfoData.end())
        {
            tmpFolderInfoMap = tmpFolderInfoIter->second;

            calculateMaxSize(folderName);
            auto tmpFolderValueIter1 = tmpFolderInfoMap.find("folderMaxSize");
            if (tmpFolderValueIter1 != tmpFolderInfoMap.end())
            {
                folderMaxSize = stod((tmpFolderValueIter1->second).c_str());
            }

            auto tmpFolderValueIter2 = tmpFolderInfoMap.find("alarmThreshold");
            if (tmpFolderValueIter2 != tmpFolderInfoMap.end())
            {
                alarmThreshold = stod(tmpFolderValueIter2->second.c_str());
            }

            auto tmpFolderValueIter3 = tmpFolderInfoMap.find("safetyThreshold");
            if (tmpFolderValueIter3 != tmpFolderInfoMap.end())
            {
                safetyThreshold = stod(tmpFolderValueIter3->second.c_str());
            }

            auto tmpFolderValueIter4 = tmpFolderInfoMap.find("folderUsingSize");
            if (tmpFolderValueIter4 != tmpFolderInfoMap.end())
            {
                folderUsingSize = stod(tmpFolderValueIter4->second.c_str());
            }
        }

        double tmpDelSize = judgeFileToFolder(tmpFileSize, folderMaxSize, folderUsingSize, alarmThreshold, safetyThreshold);

        if (tmpDelSize > 1.0)
        {
            delFileFromPath(folderName, tmpDelSize);
            newFilePath = saveFileToPath(fileName, folderName);
        }
        else if (tmpDelSize >= -0.00001 && tmpDelSize <= 0.00001)
        {
            newFilePath = saveFileToPath(fileName, folderName);
        }
        else
        {
            return newFilePath;
        }

        //保存文件信息至map
        string tmpFileName = fileName.substr(fileName.find_last_of("/") + 1);

        m_folderAllFileInfo[folderName][to_string(s_buf.st_mtime) + tmpFileName] = tmpFileName + "&" + to_string(s_buf.st_size);

        auto tmpNewFolderInfoIter = m_folderInfoData.find(folderName);
        if (tmpNewFolderInfoIter != m_folderInfoData.end())
        {
            //     // cout<<"tmpFolderInfoIter != m_folderInfoData.end()"<<__LINE__<<endl;
            auto tmpNewFolderInfoMap = tmpNewFolderInfoIter->second;
            auto tmpNewFolderValueIter = tmpNewFolderInfoMap.find("folderUsingSize");

            if (tmpNewFolderValueIter != tmpNewFolderInfoMap.end())
            {
                double useNewFolderSize = stod((tmpNewFolderValueIter->second).c_str());
                useNewFolderSize += s_buf.st_size;

                m_folderInfoData[folderName]["folderUsingSize"] = to_string(useNewFolderSize);
            }

        }
        
        //放入法规要求的地方
        // if (regulAreaFlag > 0)
        // {
        //     cpFileToRegulArea(newFilePath, regulAreaFlag);
        // }
    }
    else
    {
        Log_Info("not have filepath; tmpFolderId:{}", tmpFolderId);
    }

    return newFilePath;
}

string L3FileManager::cpFileToRegulArea(string fileName, int regulAreaFlag)
{
    std::map<string, string> tmpFolderInfoMap;
    double folderMaxSize = 0.0;
    double alarmThreshold = 0.0;
    double safetyThreshold = 0.0;
    double folderUsingSize = 0.0;
    string newFilePath = "";
    int tmpFolderId = 0;

    if (1 == regulAreaFlag)
    {
        tmpFolderId = E_AccidentAndCollision_ID;
    }
    else if (2 == regulAreaFlag)
    {
        tmpFolderId = E_NonCriticalSecurityLog_ID;
    }

    auto tmpFolderIdIter = m_folderIdInfo.find(tmpFolderId);

    if (tmpFolderIdIter != m_folderIdInfo.end())
    {
        string folderName = tmpFolderIdIter->second;

        struct stat s_buf;
        int ret = stat(fileName.c_str(), &s_buf);
        (void)ret;

        // if(!S_ISDIR(s_buf.st_mode))
        // {
        // 	// cout<<"dir_info->d_name:"<<fileName<<"s_buf.st_mtime1:"<<s_buf.st_mtime<<" s_buf.st_size"<<s_buf.st_size<<endl;
        //     // cout<<"dir_info->d_name:"<<fileName<<"s_buf.st_ctime1:"<<s_buf.st_ctime<<" s_buf.st_size"<<s_buf.st_size<<endl;
        //     // cout<<"dir_info->d_name:"<<fileName<<"s_buf.st_atime1:"<<s_buf.st_atime<<" s_buf.st_size"<<s_buf.st_size<<endl;

        // }

        double tmpFileSize = s_buf.st_size;

        auto tmpFolderInfoIter = m_folderInfoData.find(folderName);
        if (tmpFolderInfoIter != m_folderInfoData.end())
        {
            tmpFolderInfoMap = tmpFolderInfoIter->second;

            calculateMaxSize(folderName);
            auto tmpFolderValueIter1 = tmpFolderInfoMap.find("folderMaxSize");
            if (tmpFolderValueIter1 != tmpFolderInfoMap.end())
            {
                folderMaxSize = stod((tmpFolderValueIter1->second).c_str());
            }

            auto tmpFolderValueIter2 = tmpFolderInfoMap.find("alarmThreshold");
            if (tmpFolderValueIter2 != tmpFolderInfoMap.end())
            {
                alarmThreshold = stod(tmpFolderValueIter2->second.c_str());
            }

            auto tmpFolderValueIter3 = tmpFolderInfoMap.find("safetyThreshold");
            if (tmpFolderValueIter3 != tmpFolderInfoMap.end())
            {
                safetyThreshold = stod(tmpFolderValueIter3->second.c_str());
            }

            auto tmpFolderValueIter4 = tmpFolderInfoMap.find("folderUsingSize");
            if (tmpFolderValueIter4 != tmpFolderInfoMap.end())
            {
                folderUsingSize = stod(tmpFolderValueIter4->second.c_str());
            }
        }

        double tmpDelSize = judgeFileToFolder(tmpFileSize, folderMaxSize, folderUsingSize, alarmThreshold, safetyThreshold);
        if (tmpDelSize > 1.0)
        {
            delFileFromPath(folderName, tmpDelSize);
            newFilePath = cpFileToPath(fileName, folderName);
        }
        else if (tmpDelSize >= -0.00001 && tmpDelSize <= 0.00001)
        {
            newFilePath = cpFileToPath(fileName, folderName);
        }
        else
        {
            return newFilePath;
        }

        //保存文件信息至map
        string tmpFileName = fileName.substr(fileName.find_last_of("/") + 1);

        m_folderAllFileInfo[folderName][to_string(s_buf.st_mtime) + tmpFileName] = tmpFileName + "&" + to_string(s_buf.st_size);


        auto tmpNewFolderInfoIter = m_folderInfoData.find(folderName);
        if (tmpNewFolderInfoIter != m_folderInfoData.end())
        {
            auto tmpNewFolderInfoMap = tmpNewFolderInfoIter->second;
            auto tmpNewFolderValueIter = tmpNewFolderInfoMap.find("folderUsingSize");

            if (tmpNewFolderValueIter != tmpNewFolderInfoMap.end())
            {
                double useNewFolderSize = stod((tmpNewFolderValueIter->second).c_str());
                useNewFolderSize += s_buf.st_size;

                m_folderInfoData[folderName]["folderUsingSize"] = to_string(useNewFolderSize);

            }

        }
    }

    return newFilePath;
}

L3FileManager::~L3FileManager()
{
}
